﻿using BCCommon;
using BCCommon.Enums;
using BCCommon.Extensions;
using BCCommon.PaymentEnums;
using BCData.Common.SystemFinanceFlowRecord;
using BCData.Common.Wallet;
using BCData.Website.User.User;
using BCDto.Common.SystemFinanceFlowRecord;
using BCEntity.Common.SystemFinanceFlowRecord;
using BCEntity.Website.User;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace BCService.Common.SystemFinanceFlowRecord
{
    public class SystemFinanceFlowRecordService : ISystemFinanceFlowRecordService
    {
        private readonly ISystemFinanceFlowRecordData systemFinanceFlowRecordData;
        private readonly IUserData userData;
        private readonly IWalletData walletData;

        public SystemFinanceFlowRecordService(ISystemFinanceFlowRecordData systemFinanceFlowRecordData, IUserData userData, IWalletData walletData)
        {
            this.systemFinanceFlowRecordData = systemFinanceFlowRecordData;
            this.userData = userData;
            this.walletData = walletData;
        }

        public SystemFinanceFlowRecordDto WriteSystemFinanceFlowRecord(long? userId, decimal amount, string orderNo, SourceFlowDirectionType flowDirectionType, FlowType flowType, PaymentChannelType channelType)
        {
            if (userId.HasValue)
            {
                UserEntity userEntity = this.userData.GetUserByUserId(userId.Value).Result;
               
                var systemFinanceFlowRecordDto = new SystemFinanceFlowRecordDto
                {
                    Amount = amount,
                    OrderNo = orderNo,
                    Remark = $"{flowType.GetDisplayString()}: {string.Format("{0:N2}", amount)}元",
                    FlowDirection = flowDirectionType,
                    FlowType = flowType,
                    Channel = channelType,
                    UserId = userId.Value,
                    UserName = userEntity.UserName
                };

                return this.Append(systemFinanceFlowRecordDto);
            }
            else
            {
                var systemFinanceFlowRecordDto = new SystemFinanceFlowRecordDto
                {
                    Amount = amount,
                    OrderNo = orderNo,
                    Remark = $"{flowType.GetDisplayString()}: {string.Format("{0:N2}", amount)}元",
                    FlowDirection = flowDirectionType,
                    FlowType = flowType,
                    Channel = channelType,
                    UserName = ""
                };

                return this.Append(systemFinanceFlowRecordDto);
            }
        }

        public SystemFinanceFlowRecordDto Append(SystemFinanceFlowRecordDto systemFinanceFlowRecordDto)
        {
            var task = this.systemFinanceFlowRecordData.Append(systemFinanceFlowRecordDto.As<SystemFinanceFlowRecordEntity>());
            return task.GetAwaiter().GetResult().As<SystemFinanceFlowRecordDto>();
        }

        public PageableList<SystemFinanceFlowRecordDto> Query(string orderNo, long? userId, SourceFlowDirectionType? flowDirectionType, PaymentChannelType? payChannelType, FlowType? flowType, DateTime? start, DateTime? end, bool? ascending, int pageIndex = 1, int pageSize = 10)
        {
            var task = this.systemFinanceFlowRecordData.Query(orderNo, userId, flowDirectionType, payChannelType, flowType, start, end, ascending, pageIndex, pageSize);
            var result = task.GetAwaiter().GetResult();

            PageableList<SystemFinanceFlowRecordDto> pageableList = new PageableList<SystemFinanceFlowRecordDto>()
            {
                Count = result.Item2,
                Items = result.Item1.As<IEnumerable<SystemFinanceFlowRecordDto>>()
            };
            return pageableList;
        }

        public async Task<PageableList<SystemFinanceFlowRecordExtendDto>> GetAll(string orderNo, long? userId,
            SourceFlowDirectionType? flowDirectionType, PaymentChannelType? payChannelType, FlowType? flowType, DateTime? start,
            DateTime? end, bool? @ascending, int pageIndex = 1, int pageSize = 10)
        {
            var (dataList, dataCount) = await systemFinanceFlowRecordData.GetAll(orderNo, userId, flowDirectionType, payChannelType, flowType, start, end, ascending, pageIndex, pageSize);

            PageableList<SystemFinanceFlowRecordExtendDto> pageableList = new PageableList<SystemFinanceFlowRecordExtendDto>()
            {
                Count = dataCount,
                Items = dataList.As<List<SystemFinanceFlowRecordExtendDto>>()
            };
            return pageableList;
        }
    }
}